
/*
Copyright 2009 Peter Ekler, Akos Ludanyi, Budapest University of Technology and Economics, Department of Automation and Applied Informatics, Applied Mobile Research Group (AMORG) http://amorg.aut.bme.hu

This file is part of MobTorrent.

MobTorrent is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MobTorrent is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MobTorrent.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * FileSelectDialog.java
 *
 * Created on 2007. febru�r 8., 10:59
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package fileselectdialog;

import data.LocalizationSupport;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;

import Tools.Comparator;
import Tools.VectorSorter;

/**
 *
 * @author Tyrial
 */
public class MTFileSelectDialog implements CommandListener {
    
    // --- INNER CLASSES
    
    private class MyNode{
        private String name;
        private boolean dir;        
        
        MyNode(String aName, boolean aDir)
        {
            setName(aName);
            setDir(aDir);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isDir() {
            return dir;
        }

        public void setDir(boolean dir) {
            this.dir = dir;
        }

    }

    private static class DefualtComparator implements Comparator
    {
        public int compare(Object o1, Object o2)
        {
            MyNode n1 = (MyNode)o1, n2 = (MyNode)o2;

            if(n1.isDir() == n2.isDir())
                return n1.getName().toLowerCase().compareTo(n2.getName().toLowerCase());
            return (n1.isDir()) ? -1 : 1;
        }
    }

    private class MyRootRefresher extends Thread
    {                    
        public void run()
        {    
            refreshListByCurrentRoot();
            get_listBrowser().setSelectedIndex(0,true);
        }
    }     
    
    // --- VARIABLES
    
    private String currentRoot="/";
    private String[] extensions;
    private Vector currentContent;
    private List listBrowser;
    private Command backFromFileSelect;
    private Command screenCommandEnter;
    private Command screenCommandSelect;
    private Command screenCommandSelectFolder;
    private Image imageDisc;
    private Image imageRoot;
    private Image imageFolder;
    private Image imageFile;
    private Display display;
    private MTFileSelectDialogListener fileSelectDialogListener;
    private boolean fileSelection = true;
    
    // --- FUNCTIONS
    
    private void refreshListByCurrentRoot()
    {
        try
        {  
            currentContent.removeAllElements();
            get_listBrowser().deleteAll();
            get_listBrowser().setTitle(currentRoot);              
            if (currentRoot.equals("/"))
            {                
                Enumeration systems = FileSystemRegistry.listRoots();
                while(systems.hasMoreElements())
                {
                    String name = (String) systems.nextElement();
                    
                    //if (name.indexOf(":")!=-1 || name.equals("root1/")) // elliminate fake drives
                    //{                    
                        currentContent.addElement(new MyNode(name,true));
                        //get_listBrowser().append(name,get_imageDisc());
                    //}
                }

                VectorSorter.sort(currentContent, new DefualtComparator());
                for(int i = 0; i < currentContent.size(); i++)
                {
                    get_listBrowser().append(((MyNode)currentContent.elementAt(i)).getName(), get_imageDisc());
                }
            }
            else
            {
                FileConnection fileConnection = null;
                try {
                    fileConnection = (FileConnection) Connector.open("file:///"+currentRoot,Connector.READ);
                    
                    if(fileConnection.isDirectory())
                    {
                        get_listBrowser().append("..",get_imageRoot());
                        Enumeration names = fileConnection.list();
                        while(names.hasMoreElements())
                        {
                            String name = (String) names.nextElement();
                            if (name.endsWith("/"))
                            {
                                currentContent.addElement(new MyNode(name,true));
                                //get_listBrowser().append(name,get_imageFolder());
                            }
                            else if (fileSelection)
                            {   
                                if (endsWithExtensions(name))    
                                {
                                    currentContent.addElement(new MyNode(name,false));
                                    //get_listBrowser().append(name,get_imageFile());
                                }
                            }
                        }

                        VectorSorter.sort(currentContent, new DefualtComparator());
                        for(int i = 0; i < currentContent.size(); i++)
                        {
                            MyNode node = (MyNode)currentContent.elementAt(i);
                            Image img = node.isDir() ? get_imageFolder() : get_imageFile();
                            get_listBrowser().append(node.getName(), img);
                        }
                        fileConnection.close();
                    } 
                    else
                    {
                        // root selected
                        fileConnection.close();
                        currentRoot = "/";                        
                        refreshListByCurrentRoot();
                    }
                }
                catch( IOException e ){
                    // could not access the URL
                    showAlert(e.getMessage());
                }
                catch( SecurityException e ){
                    // no permission to read the directory
                    showAlert(e.getMessage());
                }            
            }        
        }
        catch (Exception e)
        {
            showAlert(e.getMessage());
            get_listBrowser().setTitle(e.getMessage());
        }
    }
    
    private void refreshList()
    {
        int selectedIndex = get_listBrowser().getSelectedIndex()-1; 
        boolean root = false;

        if (currentRoot.equals("/"))
        {
            root = true;
            selectedIndex++;                 
        }

        if (get_listBrowser().getSelectedIndex()!=0 || root)
        {                              
            MyNode tempMyNode = (MyNode)currentContent.elementAt(selectedIndex); 

            if (tempMyNode.isDir())
            {
                String selectedName =tempMyNode.getName();

                if (root)                
                    currentRoot=selectedName;                                    
                else                
                    currentRoot=currentRoot+selectedName;               

                new MyRootRefresher().start();
            }
        }
        else
        {                       
            boolean firstroot=false;

            if (getPerNums(currentRoot)==1)
            {
                currentRoot="/";
                firstroot=true;
            }
            else if (currentRoot.charAt(currentRoot.length()-1)=='/')                    
                currentRoot=currentRoot.substring(0,currentRoot.length()-1);

            if (!firstroot)
            {
                currentRoot=currentRoot.substring(0,currentRoot.lastIndexOf('/')+1);
            }

            new MyRootRefresher().start(); 
        }
    }
    
    private int getPerNums(String aPath)
    {
        int perNum=0;
        for (int i=0; i<aPath.length(); i++)
        {
            if (aPath.charAt(i)=='/')
                perNum++;
        }
        
        return perNum;
    }      
    
    public void commandAction(Command command, Displayable displayable) {
        if (command == backFromFileSelect)
        {            
            fileSelectDialogListener.selectionCancelled();
        }
        else if (command == get_screenCommandSelect() || command == List.SELECT_COMMAND)
        {                                             
            if (!currentRoot.equals("/") && get_listBrowser().getSelectedIndex()!=0)
            {                              
                MyNode tempMyNode = (MyNode)currentContent.elementAt(get_listBrowser().getSelectedIndex()-1); 
                if (!tempMyNode.isDir())
                {
                    fileSelectDialogListener.fileSelected(currentRoot+tempMyNode.getName(),tempMyNode.getName());
                }
                else
                    refreshList();                
            }
            else
                refreshList();            
        }
        else if (command == get_screenCommandSelectFolder())
        {                
            if (currentRoot.equals("/"))
            {
                MyNode tempMyNode = (MyNode)currentContent.elementAt(get_listBrowser().getSelectedIndex()); 
                if (tempMyNode.isDir())
                {
                    fileSelectDialogListener.folderSelected(tempMyNode.getName(),tempMyNode.getName());
                }
            }
            else if (!currentRoot.equals("/") && get_listBrowser().getSelectedIndex()!=0)
            {                    
                MyNode tempMyNode = (MyNode)currentContent.elementAt(get_listBrowser().getSelectedIndex()-1); 
                if (tempMyNode.isDir())
                {
                    fileSelectDialogListener.folderSelected(currentRoot+tempMyNode.getName(),tempMyNode.getName());
                }
            }       
        }        
    }
    
    /** Creates a new instance of FileSelectDialog */
    public MTFileSelectDialog(Display aDisplay, MTFileSelectDialogListener aFileSelectDialogListener)
    {
        display = aDisplay;
        fileSelectDialogListener = aFileSelectDialogListener;
    }    
    
    public void showFileSelectDialog(String[] aExtensions,boolean aFileSelection)
    {
        extensions=aExtensions;
        fileSelection=aFileSelection;
        currentContent=new Vector();        
        display.setCurrent(get_listBrowser());
        if (fileSelection)
            get_listBrowser().removeCommand(get_screenCommandSelectFolder());
        else
            get_listBrowser().addCommand(get_screenCommandSelectFolder());
        new MyRootRefresher().start();        
    }
    
    private boolean endsWithExtensions(String aName)
    {
        // if we did not set extensions then we list everything
        if (extensions==null)
            return true;
        
        for (int i=0; i<extensions.length; i++)
        {
            if (aName.endsWith(extensions[i]))
                return true;
        }
        
        return false;
    }
    
    private void showAlert(String aMessage)
    {
        Alert alert = new Alert(LocalizationSupport.getMessage("title_fileBrowser"), aMessage, null, AlertType.ERROR);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert,get_listBrowser());    
    }
    
    private List get_listBrowser() {
        if (listBrowser == null) {                      
            listBrowser = new List(LocalizationSupport.getMessage("title_fileBrowser"), Choice.IMPLICIT, new String[0], new Image[0]);
            listBrowser.addCommand(get_backCommandBackToList());
            listBrowser.addCommand(get_screenCommandSelect());
            listBrowser.addCommand(get_screenCommandSelectFolder());
            //listBrowser.setSelectCommand(get_screenCommandSelect());
            listBrowser.setCommandListener(this);
            listBrowser.setSelectedFlags(new boolean[0]);                     
        }                      
        return listBrowser;
    }
    
    private Command get_backCommandBackToList() {
        if (backFromFileSelect == null) {                       
            backFromFileSelect = new Command(LocalizationSupport.getMessage("command_back"), Command.BACK, 1);
        }                       
        return backFromFileSelect;
    }    

    private Command get_screenCommandSelect() {
        if (screenCommandSelect == null) { 
            screenCommandSelect = new Command(LocalizationSupport.getMessage("command_open"), Command.SCREEN, 2);
        }                       
        return screenCommandSelect;
    }    
    
    private Command get_screenCommandSelectFolder() {
        if (screenCommandSelectFolder == null) { 
            screenCommandSelectFolder = new Command(LocalizationSupport.getMessage("command_selectFolder"), Command.SCREEN, 3);
        }                       
        return screenCommandSelectFolder;
    }     
    
    private Image get_imageFolder() {
        if (imageFolder == null) {                       
            try {                        
                imageFolder = Image.createImage("/resources/folder.png");
            } catch (java.io.IOException exception) {
                showAlert(exception.getMessage());
            }                      
        }                       
        return imageFolder;
    }                     

    private Image get_imageFile() {
        if (imageFile == null) {                       
            try {                        
                imageFile = Image.createImage("/resources/file.png");
            } catch (java.io.IOException exception) {
                showAlert(exception.getMessage());
            }
        }                       
        return imageFile;
    }  
    
    private Image get_imageDisc() {
        if (imageDisc == null) {
            try {                        
                imageDisc = Image.createImage("/resources/disc.png");
            } catch (java.io.IOException exception) {
                showAlert(exception.getMessage());
            }
        }                       
        return imageDisc;
    }
    
    private Image get_imageRoot() {
        if (imageRoot == null) {
            try {                        
                imageRoot = Image.createImage("/resources/root.png");
            } catch (java.io.IOException exception) {
                showAlert(exception.getMessage());
            }
        }                       
        return imageRoot;
    }    
}

